# -*- coding: utf-8 -*-
import aima.search as s
#Basicamente el estado lo definimos como una tupla  donde en cada posicion se encuentra una ficha del tablero
#Desde arriba hacia abajo y de izquierda a derecha de manera continua.
class sonsin(s.Problem):#Redefinimos la clase problem
    def new_state(self,estado,pa,pb):#e = estado (lista) / pa= posicion de 0 y pb= posicion nueva de 0
        accion= {3:'Abajo',-3:'Arriba',1:'Derecha',-1:'Izquierda'}[pb-pa] #diccionario que devuelve que accion es.
        e= list(estado) #Convertimos la tupla en lista para poder modificarla...
        e[pa], e[pb]= e[pb], e[pa] #swaping the 0 between pa y pb
        return (accion, tuple(e)) #Devolvemos ya directamente el grupo de la accion y el estado nuevo para res[]
    def successor(self, e):	#Siempre lo que movemos es la posicion vacia (0)
        res= [] 	#Creamos la lista de sucesores para el estado actual.
        cp= e.index(0)
        if cp > 2: res.append(self.new_state(e, cp, cp - 3))#Mover arriba: -3 lugares
        if cp not in [0,3,6]: res.append(self.new_state(e, cp, cp - 1)) #Mover a izquierda: -1  lugar
        if cp not in [2,5,8]: res.append(self.new_state(e, cp, cp + 1)) #Mover a derecha: +1 lugar
        if cp < 6: res.append(self.new_state(e, cp, cp + 3)) #Mover abajo: +3 lugares
        return res

def heuristica(nodo):
    distancia = 0
    for x in range(0,9):
        if not(nodo.state.index(x)== EM.index(x)):
            distancia+=abs((nodo.state.index(x)/3) - (EM.index(x)/3)) + abs((nodo.state.index(x)%3) - (EM.index(x)%3))
            
if __name__ == '__main__':
    EI= (3,5,2,6,1,0,8,4,7) #Estado inicial
    EM= (0,1,2,3,4,5,6,7,8)#Estado meta
    agente= sonsin(EI,EM) #Instanciamos al agente
    path= s.breadth_first_graph_search(agente) #Pedimos que encuentre el camino segun un algoritmo
    if path is None: print 'Sin solucion'
    else:
        print 'Solucionado'
        for m in path.path()[::-1]: print str(m.action) + ":" + str(m.state)
